import { Condition, Match, MatchData, TableRow } from '../type';
import { event } from './event';

export const getMatchKey = (data: {
  website_code: string;
  category_name: string;
  option_name: string;
  option_value: string;
  category_path: string;
}) => {
  const {
    website_code,
    category_name,
    option_name,
    option_value,
    category_path,
  } = data;
  return `${website_code}-${category_name}-${category_path}-${option_name}-${option_value}`;
};

const enum Status {
  NEW,
  MODIFY,
}

// 生成condition_Key
export const genConditionKey = ({
  alias_name,
  condition_name,
}: Pick<Condition, 'condition_name' | 'alias_name'>) =>
  alias_name || condition_name;
// const isEditing = ref(false);
const status = ref(Status.NEW);
const oldValue = ref({} as TableRow);

// 新增的时候保存临时的 uuid
let tempId = '';

class ConditionTable {
  data: MatchData;
  constructor(data: MatchData) {
    this.data = data;
  }

  get rows() {
    return this.data.conditions;
  }

  get rowMap() {
    const map: Map<string, Condition> = new Map();
    this.rows.forEach(item => {
      map.set(item.condition_name, item);
    });
    return map;
  }

  get getMap() {
    const conditionMap: Map<string, Condition> = new Map();
    const matchMap: Map<string, Match> = new Map();
    this.rows.forEach(condition => {
      /**
       * 鉴于用户可以更改条件名,优先使用alias_name
       */
      conditionMap.set(genConditionKey(condition), condition);
      condition.matches.forEach(match => {
        const matchKey = getMatchKey({
          website_code: match.website_code,
          category_name: match.category_name,
          option_name: match.condition_name,
          option_value: match.condition_code,
          category_path: match.category_path,
        });
        matchMap.set(matchKey, match);
      });
    });
    return {
      matchMap,
      conditionMap,
    };
  }

  get tableData() {
    const list: TableRow[] = [];
    this.rows.forEach(item => {
      if (item.matches.length) {
        item.matches.forEach((match, index) => {
          list.push({
            rowSpan: index == 0 ? item.matches.length : 0,
            isEdit: item.isEdit,
            website: match,
            alias_name: item.alias_name || item.condition_name,
            condition_name: item.condition_name,
          });
        });
      } else {
        list.push({
          condition_name: item.condition_name,
          alias_name: item.alias_name || item.condition_name,
          website: {
            website_code: '',
            category_name: '',
            category_path: '',
            condition_name: '',
            condition_code: '',
            options: [],
            category_code: '',
          },
          isEdit: item.isEdit,
        });
      }
    });
    return list;
  }

  // 匹配条件
  addMerge(condition_name: string, row: TableRow) {
    const { conditionMap } = this.getMap;
    const condition = conditionMap.get(condition_name);
    if (condition) {
      if (
        condition.matches.some(item =>
          compare(item, row.website, [
            'category_code',
            'category_name',
            'category_path',
            'condition_code',
            'condition_name',
            'website_code',
          ])
        )
      ) {
        return;
      }
      condition.matches.push(row.website);
      event.emit('modify');
    }
  }

  // 生产条件
  addCondition(row: TableRow) {
    const { conditionMap } = this.getMap;
    const condition = conditionMap.get(row.condition_name);
    if (condition) {
      if (
        condition.matches.some(item =>
          compare(item, row.website, [
            'category_code',
            'category_name',
            'category_path',
            'condition_code',
            'condition_name',
            'website_code',
          ])
        )
      ) {
        return;
      }
      condition.matches.push(row.website);
      event.emit('modify');
      return;
    }
    // 假如condition_name改名了,要先判断conditionSet是否存在当前name
    if (conditionMap.has(row.condition_name)) {
      this.data.conditions.unshift({
        condition_name: generateUUID(),
        alias_name: row.condition_name,
        matches: [row.website],
      });
    } else {
      this.data.conditions.unshift({
        condition_name: row.condition_name,
        alias_name: row.condition_name,
        matches: [row.website],
      });
    }
    event.emit('modify');
  }

  remove(row: TableRow) {
    const { conditionMap, matchMap } = this.getMap;
    const condition = conditionMap.get(genConditionKey(row));
    if (condition) {
      if (condition.matches.length <= 1) {
        this.data.conditions = this.data.conditions.filter(
          item => item != condition
        );
        event.emit('remove', row);
        return;
      }
      const match = matchMap.get(
        getMatchKey({
          website_code: row.website.website_code,
          category_name: row.website.category_name,
          option_name: row.website.condition_name,
          option_value: row.website.condition_code,
          category_path: row.website.category_path,
        })
      );
      if (match) {
        const idx = condition.matches.findIndex(item =>
          compare(item, match, [
            'category_name',
            'category_path',
            'condition_name',
            'condition_code',
            'website_code',
          ])
        );
        condition.matches.splice(idx, 1);
        event.emit('remove', row);
      }
    }
  }

  // 新建条件
  addNew(inputRef: Ref<HTMLElement | undefined>) {
    status.value = Status.NEW;
    tempId = generateUUID();
    this.rows.unshift({
      condition_name: tempId,
      alias_name: '',
      matches: [],
      isEdit: true,
    });
    nextTick(() => {
      inputRef.value?.focus();
    });
  }

  modify(row: TableRow, inputRef: Ref<HTMLElement | undefined>) {
    status.value = Status.MODIFY;
    const find = this.rows.find(item => !!item.isEdit);
    if (!find) {
      const { conditionMap } = this.getMap;
      const condition = conditionMap.get(genConditionKey(row));
      if (condition) {
        condition.isEdit = true;
        nextTick(() => {
          oldValue.value = row;
          inputRef.value?.focus();
        });
      }
    }
  }

  save(value: string, row: TableRow, inputRef: Ref<HTMLElement | undefined>) {
    if (status.value == Status.NEW) {
      this.saveNew(value, inputRef);
      return;
    }
    if (status.value == Status.MODIFY) {
      this.saveModify(value, row);
      return;
    }
  }

  saveNew(newName: string, inputRef: Ref<HTMLElement | undefined>) {
    if (!newName) {
      this.data.conditions = this.data.conditions.filter(
        item => item.alias_name != ''
      );
      return;
    }
    const { conditionMap } = this.getMap;
    if (conditionMap.has(newName)) {
      message.warn(`条件${newName}已存在`);
      inputRef.value?.focus();
      return;
    }
    const condition = conditionMap.get(tempId);
    if (condition) {
      condition.alias_name = newName;
      condition.isEdit = false;
      event.emit('modify');
    }
    tempId = '';
  }

  saveModify(newName: string, row: TableRow) {
    const { conditionMap } = this.getMap;
    const condition = conditionMap.get(genConditionKey(row));
    const isRepeat = conditionMap.get(newName);
    if (condition) {
      if (isRepeat && newName != genConditionKey(oldValue.value)) {
        condition.isEdit = false;
        return message.warning('该名称已存在');
      }
      if (newName) {
        condition.alias_name = newName;
        event.emit('rename', {
          condition_name: condition.condition_name,
          new_name: newName,
        });
        event.emit('modify');
      }
      condition.isEdit = false;
    }
  }
}

export default ConditionTable;
